import { isDate, isObject } from "./util";


function encode(val: string): string {
  return encodeURIComponent(val)
    .replace(/%40/g, '@')
    .replace(/%3A/gi, ':')
    .replace(/%24/g, '$')
    .replace(/%2C/gi, ',')
    .replace(/%20/g, '+')
    .replace(/%5B/gi, '[')
    .replace(/%5D/gi, ']')
}

export function bulidURL(url: string,params?: any){
  /**
   * 普通参数处理
   * /api/handleRequestURL/get?a=1&b=2
   */
  // 如果params为空，直接返回url
  if(!params) return url;
  // 如果url中有哈希标记 # ，则直接返回url
  if(url.includes('#')){
    const markIndex = url.indexOf("#");
    url = url.slice(0,markIndex);
    return url;
  }

  /**
   * 数组参数处理
   * /api/handleRequestURL/get?foo[]=bar&foo[]=baz
   */
  // 定义 键值对数组，用于最后拼接url，将params中的键值对进行处理最终放入 parts中
  // parts 最后应该为 ['key=value','a=1',...]
  const parts: string [] = [];

  // 遍历params中的键值对
  Object.keys(params).forEach( key => {
    let val = params[key];
    // 如果有为null 或者 undefined 的值，不处理直接跳出循环
    if(val === null || typeof val === undefined)  return ;
    
    let valuse: string [];
    // 如果为数组，则将该值赋给临时数组变量 valuse， 用于下面遍历处理
    if( Array.isArray(val)){
      valuse = val;
      key += '[]';
    } else {
      // 如果不是数组，则强行将其变为数组进行处理
      valuse = [val];
    }


    valuse.forEach((val)=>{
      if(isDate(val)){
        val = val.toISOString() ;
      }else if(isObject(val)){
        val = JSON.stringify(val);
      }
      parts.push(`${encode(key)}=${encode(val)}`);
    })
  });

  let serializedParams  = parts.join('&');
  if(serializedParams) {
    // 判断原始url中是否有已存在的参数，即判断是否有'?',
    // 如果有，则将处理后的键值对加'&'拼接在后面，
    // 如果没有，则将处理后的键值对加'?'拼接在后面
    url += (url.includes('?') ? '&' : '?') + serializedParams;
  }

  return url;
}